using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;

#if MINI
using SecretLabs.NETMF.Hardware.NetduinoMini;
#else
using SecretLabs.NETMF.Hardware.Netduino;
#endif

namespace codebase
{
    public abstract class BaseProgramSPE
    {
        #region Variables

#if NDS
        public NDSTouchscreen nds;
#endif
        public UI.Renderer_4DSPE screen = new UI.Renderer_4DSPE();

        public Point point = new Point(0,0);

        public long lasttick = DateTime.Now.Ticks / 10000;
        private int _fps = 0;
        public int fps = 0;
        public bool showfps = true;

        #endregion

        #region Main, Update, Draw

        public void Run()
        {
            Initialize();

            while (true)
            {
                Update();
                _fps++;

                long now = DateTime.Now.Ticks / 10000;
                if (now - lasttick >= 1000)
                {
                    fps = _fps;
                    _fps = 0;
                    lasttick = now;

                    Draw();
                }
            }
        }

        public virtual void Initialize()
        {
#if MINI
            screen.SPE.Initialize(SerialPorts.COM1, 9600, Pins.GPIO_PIN_10);
            screen.SPE.SetBaudRate((int)SPE.BAUD115200, 115200);
#else
            screen.SPE.Initialize(SerialPorts.COM1, 115200, Pins.GPIO_PIN_D4);
            //screen.SPE.SetBaudRate((int)SPE.BAUD115200, 115200);
#endif

#if PICASO
            screen.SPE.TouchEnable();
            screen.SPE.SetFont((int)SPE.FONT1);
#else

#if NDS
#if MINI
            nds = new NDSTouchscreen(Pins.GPIO_PIN_20, Pins.GPIO_PIN_19, Pins.GPIO_PIN_18, Pins.GPIO_PIN_17,
                AnalogChannels.ANALOG_PIN_5,AnalogChannels.ANALOG_PIN_6,
                gfx.Width, gfx.Height);
#else
            nds = new NDSTouchscreen(Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D7, Pins.GPIO_PIN_D8,
                AnalogChannels.ANALOG_PIN_A0,AnalogChannels.ANALOG_PIN_A1,
                gfx.Width, gfx.Height);
#endif
#endif

#endif
        }

        public virtual void Update()
        {
            checkTouchScreen();
        }

        public virtual void Draw()
        {
            if (showfps)
            {
                screen.DrawText(Debug.GC(false).ToString(), screen.Width - 35, screen.Height - screen.CharacterHeight, false, ColorExtensions.BLACK16, ColorExtensions.WHITE16);
            }
        }

        public void checkTouchScreen()
        {
#if PICASO
            point = screen.SPE.TouchScan();
#else
#if NDS
            point = nds.SPE.Scan();
#endif
#endif
        }

        #endregion

        #region Functions

        public void initMedia()
        {
            screen.SPE.MediaInit();
        }

        public void demoVideo()
        {
            screen.SPE.SetByteAddress((int)0x00, (int)0x8200);

            for (int i = 400; i < 450; i++)
            {
                screen.SPE.DisplayVideoFrameRAW(0, 0, i);
            }

        }

        public void demoRGB()
        {
            screen.SPE.BackgroundColor(ColorExtensions.RGB16(255, 0, 0));
            screen.Clear();

            Thread.Sleep(200);

            screen.SPE.BackgroundColor(ColorExtensions.RGB16(0, 255, 0));
            screen.Clear();

            Thread.Sleep(200);

            screen.SPE.BackgroundColor(ColorExtensions.RGB16(0, 0, 255));
            screen.Clear();

            Thread.Sleep(200);
        }
        #endregion
    }
}
